package com.fingard.dsp.bank.directbank.fubon01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

public class FUBON01SinglePay extends FUBON01Base implements ISinglePay {
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    private static final String SELECTRECEIPT = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? and BANKCODE=?;";

    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            //全局流水号
            String transSeqId = p_req1908.reqHeader.transSeqID;
            transSeqId = bankFront.corpNo + "01" + "302020" + Format.Date8Format.format(new Date()) + "00" + transSeqId.substring(transSeqId.length() - 8, transSeqId.length());

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            FUBON01Header fubon01Header = new FUBON01Header();
            fubon01Header.ServiceCode = "06001030002";//服务唯一标识，由EAI提供
            fubon01Header.ServiceScene = "01";//服务场景
            fubon01Header.InitiatorId = "203010";//发起方系统编号
            fubon01Header.ServiceId = "302020";//服务系统编号
            fubon01Header.TranDate = Format.Date8Format.format(new Date());//前台交易日期 YYYYMMDD
            fubon01Header.TranTime = Format.Time6Format.format(new Date());//前台交易时间 hhmmss
            fubon01Header.OrgConSeqNo = transSeqId;//发起方流水号 全局流水号
            fubon01Header.ConsumerSeqNo = transSeqId;//消费方流水号 调用方产生流水号
            fubon01Header.TellerNo = bankFront.operator;
            fubon01Header.BranchId = bankFront.org;
            fubon01Header.FileFlag = "0";//文件标识 1-有文件，0-无文件
            writeCommonHeader(xmlWriter, fubon01Header);
            XElement tmpXElement = new XElement("Body", "");

            tmpXElement.addChild(new XElement("Direction", "0"));//往来标志 固定填：O
            tmpXElement.addChild(new XElement("Format", ""));//支付业务类型
            tmpXElement.addChild(new XElement("Ccy", getBankConfig().getMapValueByKey("currencyMapping2", p_req1908.singleDetail.payCur)));//币种
            tmpXElement.addChild(new XElement("BusiType", ""));//业务类型编码
            tmpXElement.addChild(new XElement("TranCategory", "TMS"));//业务种类编码
            tmpXElement.addChild(new XElement("TranAmt", p_req1908.singleDetail.payAmount));//金额
            tmpXElement.addChild(new XElement("PayerAcct", p_req1908.singleDetail.payAct));//付款人账号
            tmpXElement.addChild(new XElement("PayerName", p_req1908.singleDetail.payName));//付款人名称
            tmpXElement.addChild(new XElement("Branch", bankFront.org));//？？？交易机构
            tmpXElement.addChild(new XElement("PayerAddr", ""));//付款人地址
            tmpXElement.addChild(new XElement("PayerPhoneNo", ""));//付款人联系电话
            tmpXElement.addChild(new XElement("PayerPaperType", ""));//付款人证件类型
            String payerAcctCode = getBankConfig().getMapValueByKey("accType1908", p_req1908.singleDetail.payAct);
            if(StringHelper.isNullOrEmpty(payerAcctCode)){
                payerAcctCode="CA";
            }
            tmpXElement.addChild(new XElement("PayerAcctCode", payerAcctCode));//付款人账户类型
            tmpXElement.addChild(new XElement("PayerPaperNo", ""));//付款人证件号码
            tmpXElement.addChild(new XElement("ActualPayerAcct", p_req1908.singleDetail.payAct));//实际扣款账号
            tmpXElement.addChild(new XElement("ActualPayerName", p_req1908.singleDetail.payName));//实际扣款户名
            tmpXElement.addChild(new XElement("ActualPayerAcctType", payerAcctCode)); //实际扣款帐户类型
            tmpXElement.addChild(new XElement("PayeeRcvBank", p_req1908.singleDetail.cnapsCode));//收款行行号
            tmpXElement.addChild(new XElement("PayeeName", p_req1908.singleDetail.recName));//收款人名称
            tmpXElement.addChild(new XElement("PayeeAcct", p_req1908.singleDetail.recAct));//收款人账号
            tmpXElement.addChild(new XElement("PayeeBankCode", p_req1908.singleDetail.cnapsCode));//收款人开户行行号
            tmpXElement.addChild(new XElement("PayeeCityCode", ""));//收款人城市代码
            tmpXElement.addChild(new XElement("PayeeAddr", ""));//收款人地址
            tmpXElement.addChild(new XElement("RcvBankCode", p_req1908.singleDetail.cnapsCode));//接收行行号
            tmpXElement.addChild(new XElement("Priority", ""));//优先级
            tmpXElement.addChild(new XElement("IsIndividual", p_req1908.singleDetail.isPrivate.equals("1") ? "SA" : "CA"));//对公对私标志 SA:对私CA:对公
            tmpXElement.addChild(new XElement("OrigMsgId", ""));//原报文标示号 当业务类型为C208、A105时必填,其余为空
            tmpXElement.addChild(new XElement("OrigBranchId", ""));//原发起参与机构号 当业务类型为C208、A105时必填,其余为空
            tmpXElement.addChild(new XElement("Purpose", p_req1908.singleDetail.purpose));//用途
            tmpXElement.addChild(new XElement("Postscript", p_req1908.singleDetail.abstractATS));//附言(放对账码)
            tmpXElement.addChild(new XElement("FastFlag", ""));//加急标志
            tmpXElement.addChild(new XElement("FeeFlag", "1"));//计费标志（0：不计费；1：自动计费；2：手工计费）; 如果支付系统记账,则必填
            tmpXElement.addChild(new XElement("TrialFlag", "N"));//试算标志 Y:试算N:转账
            tmpXElement.addChild(new XElement("DelayTime", "N"));//预约支付时间 N:非预约 预约则时间按此格式:YYYYMMDD HH:mm:ss
            nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();


            //gxp通讯报文头
            fubon01Header.glbTrSeq = transSeqId;
            fubon01Header.recvId = "UPPF";//服务方ID
            String gxpHeader = writeGxpHeader(fubon01Header, xmlWriter.toXmlString());


            String[] tmpStrRet = sendToBankPay(gxpHeader, gxpHeader + xmlWriter.toXmlString());
//            String[] tmpStrRet = {"", "<service><GapsAppHead><RespCode>000000</RespCode><RespMsg>交易成功</RespMsg><OrgConSeqNo>302150145737</OrgConSeqNo><ConsumerSeqNo>446127</ConsumerSeqNo><FileFlag>0</FileFlag><TranDate>20200302</TranDate><TranTime>150148</TranTime><TellerNo>5008888</TellerNo><BranchId>501000</BranchId><TellerPassword></TellerPassword><TellerLevel></TellerLevel><TellerType></TellerType><ApprFlag></ApprFlag><ApprTellerArray><ApprTellerNo></ApprTellerNo><ApprBranchId></ApprBranchId><ApprTellerLevel></ApprTellerLevel><ApprTellerType></ApprTellerType></ApprTellerArray><AuthTellerInfo><AuthTellerNo></AuthTellerNo><AuthBranchId></AuthBranchId><AuthTellerPassword></AuthTellerPassword><AuthTellerLevel></AuthTellerLevel><AuthTellerType></AuthTellerType></AuthTellerInfo><AuthFlag></AuthFlag><BckFld1></BckFld1><BckFld2></BckFld2><BckFld3></BckFld3><BckFld4></BckFld4><BckFld5></BckFld5></GapsAppHead><Body><TranList><TranArray><Format>BEPS</Format><ChargeArray><ChgSettleAcctType></ChgSettleAcctType><ChgAcctNo></ChgAcctNo><ChgCcy></ChgCcy><ChgAcctType></ChgAcctType><ChargeType></ChargeType><ChgAmt></ChgAmt><ChgMethod></ChgMethod></ChargeArray></TranArray></TranList></Body></service>"};

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/service/GapsAppHead/RespCode");
                    String returnMsg = tmpBkReader.getFirstText("/service/GapsAppHead/RespMsg");
                    tmpRetAtsDetail.respCode = "0";
                    tmpRetAtsDetail.respInfo = returnMsg;
                    tmpRetAtsDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    tmpRetAtsDetail.transState = returnCode;
                    tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
                    if (returnCode.equals("000000")) {
                        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                        JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, p_req1908.reqHeader.bankCode, fubon01Header.TranDate, p_req1908.singleDetail.askNumber, transSeqId});
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = "转账支付时候出现异常！";
            WriteBankLogLn("转账支付时候出现异常,异常信息：" + e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            //全局流水号
            String transSeqId = p_req1944.reqHeader.transSeqID;
            transSeqId = bankFront.corpNo + "01" + "302020" + Format.Date8Format.format(new Date()) + "00" + transSeqId.substring(transSeqId.length() - 8, transSeqId.length());

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            FUBON01Header fubon01Header = new FUBON01Header();
            fubon01Header.ServiceCode = "06002030002";//服务唯一标识，由EAI提供
            fubon01Header.ServiceScene = "01";//服务场景
            fubon01Header.InitiatorId = "203010";//发起方系统编号
            fubon01Header.ServiceId = "302020";//服务系统编号
            fubon01Header.TranDate = Format.Date8Format.format(new Date());//前台交易日期 YYYYMMDD
            fubon01Header.TranTime = Format.Time6Format.format(new Date());//前台交易时间 hhmmss
            fubon01Header.OrgConSeqNo = transSeqId;//发起方流水号 全局流水号
            fubon01Header.ConsumerSeqNo = transSeqId;//消费方流水号 调用方产生流水号
            fubon01Header.TellerNo = bankFront.operator;
            fubon01Header.BranchId = bankFront.org;
            fubon01Header.FileFlag = "0";//文件标识 1-有文件，0-无文件
            writeCommonHeader(xmlWriter, fubon01Header);

            //获取原支付时的流水号
            Map<String, Object> map = JDBCHelper.execQuerySingle(conn, SELECTRECEIPT, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
            if (map.size() == 0) {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = "没有这条请求映射的流水号！";
                retAts.writeRetDetail(tmpRetAtsDetail);
                return retAts;
            }
            xmlWriter.writeStartElement("Body");
            xmlWriter.writeElementString("RefNo", map.get("BANKREQSEQID").toString());//？？？三方渠道流水号 流水号和开始结束日期二者必输其一
            xmlWriter.writeElementString("StartDate", "");//起始日期
            xmlWriter.writeElementString("EndDate", "");//终止日期
            xmlWriter.writeElementString("TerminalId", "");//终端号
            xmlWriter.writeElementString("PgupOrPgdn", "");//上翻/下翻标志 "取值范围：0- 上翻1- 下翻默认0"
            xmlWriter.writeElementString("TotalNum", "");//本页记录总数
            xmlWriter.writeElementString("CurrentNum", "");//当前记录号
            xmlWriter.writeElementString("PageStart", "");//本页第一笔标志
            xmlWriter.writeElementString("PageEnd", "");//本页最后一笔标志
            xmlWriter.writeElementString("TotalRows", "");//总笔数
            xmlWriter.writeElementString("TotalPages", "");//总页数
            xmlWriter.writeElementString("TotalFlag", "");//汇总标志 "取值范围：N-不查询总笔数总页数E-指定总笔数计算查询页数O-动态计算查询结果页数默认为N"
            xmlWriter.writeEndDocument();

            //gxp通讯报文头
            fubon01Header.glbTrSeq = transSeqId;
            fubon01Header.recvId = "UPPF";//服务方ID
            String gxpHeader = writeGxpHeader(fubon01Header, xmlWriter.toXmlString());

            String[] tmpStrRet = sendToBankPay(gxpHeader, gxpHeader + xmlWriter.toXmlString());
//        String[] tmpStrRet = {"", "<service><GapsAppHead><RespCode>000000</RespCode><RespMsg>交易成功</RespMsg><OrgConSeqNo>302150145737</OrgConSeqNo><ConsumerSeqNo>446226</ConsumerSeqNo><FileFlag>0</FileFlag><TranDate>20200302</TranDate><TranTime>153458</TranTime><TellerNo>5008888</TellerNo><BranchId>501000</BranchId><TellerPassword></TellerPassword><TellerLevel></TellerLevel><TellerType></TellerType><ApprFlag></ApprFlag><ApprTellerArray><ApprTellerNo></ApprTellerNo><ApprBranchId></ApprBranchId><ApprTellerLevel></ApprTellerLevel><ApprTellerType></ApprTellerType></ApprTellerArray><AuthTellerInfo><AuthTellerNo></AuthTellerNo><AuthBranchId></AuthBranchId><AuthTellerPassword></AuthTellerPassword><AuthTellerLevel></AuthTellerLevel><AuthTellerType></AuthTellerType></AuthTellerInfo><AuthFlag></AuthFlag><BckFld1></BckFld1><BckFld2></BckFld2><BckFld3></BckFld3><BckFld4></BckFld4><BckFld5></BckFld5></GapsAppHead><Body><TranList><TranArray><RefNo>IROUTE00200302150144000001</RefNo><IrouteRefNo>IROUTE00200302150144000001</IrouteRefNo><TranRefNo></TranRefNo><TranDate>20200302</TranDate><ConsignDate></ConsignDate><Format>BEPS</Format><SourceType>ecms</SourceType><PayerAcct>10000020100003970</PayerAcct><PayerName>福建东丽鲁能纸业股份有限</PayerName><PayeeAcct>10000020100013232</PayeeAcct><PayeeName>青岛克莉佳盛科教集团股份</PayeeName><TranAmt>1</TranAmt><RcvBankCode>309391000011</RcvBankCode><BusiStatus>0</BusiStatus><ProcStatus></ProcStatus><ErrorCode></ErrorCode><ErrorReason></ErrorReason><CoreRefNo></CoreRefNo><Balance></Balance></TranArray></TranList></Body></service>"};
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/service/GapsAppHead/RespCode");
                    String returnMsg = tmpBkReader.getFirstText("/service/GapsAppHead/RespMsg");
                    if ("000000".equals(returnCode)) {
                        String state = tmpBkReader.getFirstText("/service/Body/TranList/TranArray/BusiStatus");
                        //0：成功
                        //1：失败
                        //2：处理中
                        //4：已退汇
                        tmpRetAtsDetail.respCode = "0";
                        tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                        tmpRetAtsDetail.transState = returnCode + "+" + state;
                        tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
//                    tmpRetAtsDetail.outTransID =tmpBkReader.getFirstText("/service/Body/TranList/TranArray/CoreRefNo");
                        tmpRetAtsDetail.transAmt = tmpBkReader.getFirstText("/service/Body/TranList/TranArray/TranAmt");
                    } else {
                        tmpRetAtsDetail.respCode = "0";
                        tmpRetAtsDetail.respInfo = returnMsg;
                        tmpRetAtsDetail.transState = returnCode;
                        tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
